#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
主窗口模块
应用程序主界面
"""

import os
import sys
import logging
import base64
from pathlib import Path
from typing import Optional, Dict, Any

from PySide6.QtCore import Qt, QSettings, QSize, QPoint, QByteArray
from PySide6.QtWidgets import (QMainWindow, QApplication, QMenuBar, QToolBar,
                              QStatusBar, QMenu, QMessageBox, QDialog,
                              QFileDialog, QDockWidget, QTabWidget, QLabel)
from PySide6.QtGui import QIcon, QKeySequence, QAction, QActionGroup

from ui.sql_editor import SQLEditorWidget
from ui.dock_widgets import TableSchemaDock, QueryHistoryDock, ResultsDock
from ui.dialogs.file_open import FileOpenDialog
from ui.dialogs.preferences import PreferencesDialog
from ui.dialogs.error_dialog import show_error, show_exception
from ui.style_manager import get_style_manager, apply_modern_theme, get_icon
from ui.widgets.export_status import ExportStatusWidget

from core.file_loader import get_file_loader
from config.settings import settings
from config.constants import APP_NAME, APP_VERSION
from core.i18n import tr


# 初始化日志记录器
logger = logging.getLogger("main_window")


class MainWindow(QMainWindow):
    """应用程序主窗口"""
    
    def __init__(self):
        """初始化主窗口"""
        super().__init__()
        self.file_loader = get_file_loader()
        self.style_manager = get_style_manager()
        
        self.setWindowTitle(f"{APP_NAME} v{APP_VERSION}")
        self.resize(1200, 800)
        
        # 应用现代化主题
        apply_modern_theme()
        
        # 初始化UI
        self._init_ui()
        
        # 设置图标
        self._setup_icons()
        
        # 加载窗口状态
        self._load_window_state()
        
        # 连接信号
        self._connect_signals()
        
    def _init_ui(self):
        """初始化UI"""
        # 设置中央部件
        self.sql_editor = SQLEditorWidget()
        self.setCentralWidget(self.sql_editor)
        
        # 创建菜单栏
        self._create_menu_bar()
        
        # 注意：工具栏已被删除
        # self._create_tool_bar()
        
        # 创建状态栏
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        
        # 添加SQL编辑器状态标签
        self.sql_status_label = QLabel(tr("status_ready", "就绪"))
        self.status_bar.addWidget(self.sql_status_label, 1)
        
        # 添加导出状态组件
        self.export_status_widget = ExportStatusWidget()
        self.status_bar.addPermanentWidget(self.export_status_widget)
        
        # 添加光标位置标签
        self.cursor_position_label = QLabel("行 1, 列 1")
        self.cursor_position_label.setObjectName("cursor_position_label")
        self.status_bar.addPermanentWidget(self.cursor_position_label)
        
        # 创建停靠窗口
        self._create_dock_widgets()
        
        # 在初始化完成后安排一次布局调整
        from PySide6.QtCore import QTimer
        QTimer.singleShot(100, self._adjust_dock_sizes)
    
    def _setup_icons(self):
        """设置图标"""
        # 设置窗口图标
        self.setWindowIcon(get_icon("database"))
        
        # 为菜单项设置图标
        try:
            menu_bar = self.menuBar()
            if menu_bar:
                menu_actions = menu_bar.actions()
                
                # 文件菜单图标
                if len(menu_actions) > 0:
                    file_menu = menu_actions[0].menu()
                    if file_menu:
                        actions = file_menu.actions()
                        if len(actions) > 0:
                            actions[0].setIcon(get_icon("folder-open"))  # 打开文件
                        if len(actions) > 3:
                            actions[3].setIcon(get_icon("settings"))     # 偏好设置
                        if len(actions) > 5:
                            actions[5].setIcon(get_icon("close"))        # 退出
                
                # 编辑菜单图标
                if len(menu_actions) > 1:
                    edit_menu = menu_actions[1].menu()
                    if edit_menu:
                        actions = edit_menu.actions()
                        if len(actions) > 2:
                            actions[2].setIcon(get_icon("cut"))      # 剪切
                        if len(actions) > 3:
                            actions[3].setIcon(get_icon("copy"))     # 复制
                        if len(actions) > 4:
                            actions[4].setIcon(get_icon("clipboard")) # 粘贴
                
                # 帮助菜单图标
                if len(menu_actions) > 3:
                    help_menu = menu_actions[3].menu()
                    if help_menu:
                        actions = help_menu.actions()
                        if len(actions) > 0:
                            actions[0].setIcon(get_icon("help"))     # 关于
        except RuntimeError as e:
            # 如果菜单对象已被删除，记录错误但不中断程序
            print(f"{tr('warning_menu_deleted', '警告：设置图标时菜单对象已被删除')}: {e}")
        
    def _create_menu_bar(self):
        """创建菜单栏"""
        # 文件菜单
        file_menu = self.menuBar().addMenu(tr("menu_file", "文件"))
        
        # 打开文件动作
        open_action = QAction(tr("action_open_file", "打开文件..."), self)
        open_action.setShortcut(QKeySequence.Open)
        open_action.triggered.connect(self._show_open_dialog)
        file_menu.addAction(open_action)
        
        # 最近打开的文件
        self.recent_menu = QMenu(tr("action_recent_files", "最近打开的文件"), self)
        file_menu.addMenu(self.recent_menu)
        
        # 更新最近文件菜单
        self._update_recent_files_menu()
        
        file_menu.addSeparator()
        
        # 偏好设置
        preferences_action = QAction(tr("action_preferences", "偏好设置..."), self)
        preferences_action.triggered.connect(self._show_preferences)
        file_menu.addAction(preferences_action)
        
        file_menu.addSeparator()
        
        # 退出动作
        exit_action = QAction(tr("action_exit", "退出"), self)
        exit_action.setShortcut(QKeySequence.Quit)
        exit_action.triggered.connect(self.close)
        file_menu.addAction(exit_action)
        
        # 编辑菜单
        edit_menu = self.menuBar().addMenu(tr("menu_edit", "编辑"))
        
        # 撤销动作
        undo_action = QAction(tr("action_undo", "撤销"), self)
        undo_action.setShortcut(QKeySequence.Undo)
        edit_menu.addAction(undo_action)
        
        # 重做动作
        redo_action = QAction(tr("action_redo", "重做"), self)
        redo_action.setShortcut(QKeySequence.Redo)
        edit_menu.addAction(redo_action)
        
        edit_menu.addSeparator()
        
        # 剪切动作
        cut_action = QAction(tr("action_cut", "剪切"), self)
        cut_action.setShortcut(QKeySequence.Cut)
        edit_menu.addAction(cut_action)
        
        # 复制动作
        copy_action = QAction(tr("action_copy", "复制"), self)
        copy_action.setShortcut(QKeySequence.Copy)
        edit_menu.addAction(copy_action)
        
        # 粘贴动作
        paste_action = QAction(tr("action_paste", "粘贴"), self)
        paste_action.setShortcut(QKeySequence.Paste)
        edit_menu.addAction(paste_action)
        
        # 视图菜单 - 先创建空菜单，稍后在_create_view_menu中填充内容
        self.view_menu = self.menuBar().addMenu(tr("menu_view", "视图"))
        
        # 帮助菜单
        help_menu = self.menuBar().addMenu(tr("menu_help", "帮助"))
        
        # 关于动作
        about_action = QAction(tr("action_about", "关于"), self)
        about_action.triggered.connect(self._show_about)
        help_menu.addAction(about_action)
        
    def _create_tool_bar(self):
        """创建工具栏"""
        toolbar = QToolBar(tr("toolbar_main", "主工具栏"))
        toolbar.setMovable(False)
        toolbar.setIconSize(QSize(16, 16))
        self.addToolBar(toolbar)
        
        # 打开文件按钮
        open_action = QAction(tr("action_open_file_toolbar", "打开文件"), self)
        open_action.triggered.connect(self._show_open_dialog)
        toolbar.addAction(open_action)
        
        toolbar.addSeparator()
        
        # 执行查询按钮
        run_action = QAction(tr("action_execute_query", "执行查询"), self)
        run_action.triggered.connect(self._execute_current_query)
        toolbar.addAction(run_action)
        
        # 停止查询按钮
        stop_action = QAction(tr("action_stop_query", "停止查询"), self)
        stop_action.triggered.connect(self._stop_current_query)
        toolbar.addAction(stop_action)
        
        # 格式化按钮
        format_action = QAction(tr("action_format_sql", "格式化SQL"), self)
        format_action.triggered.connect(self._format_current_query)
        toolbar.addAction(format_action)
        
    def _create_dock_widgets(self):
        """创建停靠窗口"""
        # 表结构窗口
        self.schema_dock = TableSchemaDock(self)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.schema_dock)
        
        # 查询历史窗口
        self.history_dock = QueryHistoryDock(self)
        self.addDockWidget(Qt.RightDockWidgetArea, self.history_dock)
        
        # 查询结果窗口
        self.results_dock = ResultsDock(self)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.results_dock)
        
        # 设置所有停靠窗口为可移动、可浮动、可关闭
        for dock in [self.schema_dock, self.history_dock, self.results_dock]:
            dock.setFeatures(QDockWidget.DockWidgetMovable | 
                           QDockWidget.DockWidgetFloatable |
                           QDockWidget.DockWidgetClosable)
            dock.setAllowedAreas(Qt.AllDockWidgetAreas)
        
        # 设置高级停靠选项
        self.setDockOptions(QMainWindow.AllowNestedDocks | 
                          QMainWindow.AllowTabbedDocks |
                          QMainWindow.GroupedDragging)
        
        # 设置停靠窗口标签位置
        self.setTabPosition(Qt.AllDockWidgetAreas, QTabWidget.North)
        
        # 创建视图菜单
        self._create_view_menu()
        
        # 调整窗口布局
        # 表结构占满左侧
        self.resizeDocks([self.schema_dock], [self.width() * 0.2], Qt.Horizontal)
        
        # 查询历史占满右侧
        self.resizeDocks([self.history_dock], [self.width() * 0.2], Qt.Horizontal)
        
        # 结果窗口占中间下部的整个宽度
        self.resizeDocks([self.results_dock], [self.height() * 0.4], Qt.Vertical)
        
    def _create_view_menu(self):
        """填充视图菜单内容"""
        # 使用已经创建的视图菜单
        view_menu = self.view_menu
        
        # 添加停靠窗口切换动作
        view_menu.addAction(self.schema_dock.toggleViewAction())
        view_menu.addAction(self.history_dock.toggleViewAction())
        view_menu.addAction(self.results_dock.toggleViewAction())
        
        # 添加分隔线
        view_menu.addSeparator()
        
        # 添加主题菜单
        theme_menu = view_menu.addMenu(tr("menu_theme", "主题"))
        
        # 创建主题动作组（确保只能选择一个）
        self.theme_action_group = QActionGroup(self)
        
        # 跟随系统主题
        auto_theme_action = QAction(tr("theme_auto", "跟随系统"), self)
        auto_theme_action.setCheckable(True)
        auto_theme_action.setData("auto")
        auto_theme_action.triggered.connect(lambda: self._change_theme("auto"))
        self.theme_action_group.addAction(auto_theme_action)
        theme_menu.addAction(auto_theme_action)
        
        # 浅色主题
        light_theme_action = QAction(tr("theme_light", "浅色"), self)
        light_theme_action.setCheckable(True)
        light_theme_action.setData("modern_light")
        light_theme_action.triggered.connect(lambda: self._change_theme("modern_light"))
        self.theme_action_group.addAction(light_theme_action)
        theme_menu.addAction(light_theme_action)
        
        # 深色主题
        dark_theme_action = QAction(tr("theme_dark", "深色"), self)
        dark_theme_action.setCheckable(True)
        dark_theme_action.setData("modern_dark")
        dark_theme_action.triggered.connect(lambda: self._change_theme("modern_dark"))
        self.theme_action_group.addAction(dark_theme_action)
        theme_menu.addAction(dark_theme_action)
        
        # 设置当前选中的主题
        self._update_theme_menu()
        
        # 添加分隔线
        view_menu.addSeparator()
        
        # 添加布局选项
        tabbed_layout = QAction(tr("layout_tabbed", "标签式布局"), self)
        tabbed_layout.triggered.connect(self._create_tabbed_layout)
        view_menu.addAction(tabbed_layout)
        
        horizontal_layout = QAction(tr("layout_horizontal", "水平布局"), self)
        horizontal_layout.triggered.connect(self._create_horizontal_layout)
        view_menu.addAction(horizontal_layout)
        
        vertical_layout = QAction(tr("layout_vertical", "垂直布局"), self)
        vertical_layout.triggered.connect(self._create_vertical_layout)
        view_menu.addAction(vertical_layout)
        
    def _create_tabbed_layout(self):
        """创建标签式布局"""
        # 首先移除所有停靠窗口
        for dock in [self.schema_dock, self.history_dock, self.results_dock]:
            self.removeDockWidget(dock)
        
        # 重新添加窗口并创建标签
        self.addDockWidget(Qt.LeftDockWidgetArea, self.schema_dock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.history_dock)
        self.tabifyDockWidget(self.schema_dock, self.history_dock)
        
        # 添加结果窗口到底部
        self.addDockWidget(Qt.BottomDockWidgetArea, self.results_dock)
        
        # 确保所有窗口可见
        self.schema_dock.show()
        self.schema_dock.raise_()  # 激活第一个标签
        self.history_dock.show()
        self.results_dock.show()
        
    def _create_horizontal_layout(self):
        """创建水平布局"""
        # 首先移除所有停靠窗口
        for dock in [self.schema_dock, self.history_dock, self.results_dock]:
            self.removeDockWidget(dock)
        
        # 重新添加窗口到水平位置
        self.addDockWidget(Qt.LeftDockWidgetArea, self.schema_dock)
        self.addDockWidget(Qt.RightDockWidgetArea, self.history_dock)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.results_dock)
        
        # 确保所有窗口可见
        self.schema_dock.show()
        self.history_dock.show()
        self.results_dock.show()
        
    def _create_vertical_layout(self):
        """创建垂直布局"""
        # 首先移除所有停靠窗口
        for dock in [self.schema_dock, self.history_dock, self.results_dock]:
            self.removeDockWidget(dock)
        
        # 重新添加窗口到垂直位置
        self.addDockWidget(Qt.LeftDockWidgetArea, self.schema_dock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.history_dock)
        self.splitDockWidget(self.schema_dock, self.history_dock, Qt.Vertical)
        
        # 添加结果窗口到右侧
        self.addDockWidget(Qt.RightDockWidgetArea, self.results_dock)
        
        # 确保所有窗口可见
        self.schema_dock.show()
        self.history_dock.show()
        self.results_dock.show()
        
    def _connect_signals(self):
        """连接信号"""
        # 表结构窗口生成查询信号
        self.schema_dock.query_generated.connect(self.sql_editor.insert_sql)
        
        # 查询历史窗口选择查询信号
        self.history_dock.query_selected.connect(self.sql_editor.execute_sql)
        
        # 文件加载信号
        self.file_loader.loading_completed.connect(self._on_file_loaded)
        
        # 连接SQL编辑器的查询执行信号到结果窗口
        for i in range(self.sql_editor.tab_widget.count()):
            tab = self.sql_editor.tab_widget.widget(i)
            if tab:
                tab.query_executed.connect(self._on_query_executed)
        
        # 监听新增标签页信号
        self.sql_editor.tab_added.connect(self._on_tab_added)
        
        # 连接当前标签页的状态信号
        current_tab = self.sql_editor.current_tab()
        if current_tab:
            self._connect_tab_signals(current_tab)
            
        # 监听标签页切换
        self.sql_editor.tab_widget.currentChanged.connect(self._on_tab_changed)
    
    def _connect_tab_signals(self, tab):
        """连接标签页的信号"""
        if tab:
            tab.status_changed.connect(self._update_sql_status)
            tab.cursor_position_changed.connect(self._update_cursor_position)
    
    def _on_tab_changed(self, index):
        """标签页切换时重新连接信号"""
        current_tab = self.sql_editor.current_tab()
        if current_tab:
            self._connect_tab_signals(current_tab)
            # 更新状态显示
            self._update_sql_status(tr("status_ready", "就绪"))
            self._update_cursor_position(1, 1)
    
    def _update_sql_status(self, status):
        """更新SQL编辑器状态"""
        self.sql_status_label.setText(status)
    
    def _update_cursor_position(self, line, column):
        """更新光标位置显示"""
        self.cursor_position_label.setText(tr("sql_cursor_position", "行 {0}, 列 {1}").format(line, column))
        
    def _show_open_dialog(self):
        """显示打开文件对话框"""
        dialog = FileOpenDialog(self)
        dialog.file_selected.connect(self._load_file)
        dialog.exec_()
        
    def _load_file(self, file_path: str, table_name: str, options: Dict[str, Any]):
        """加载文件
        
        Args:
            file_path: 文件路径
            table_name: 表名
            options: 加载选项
        """
        # 更新状态栏
        self.sql_status_label.setText(f"{tr('status_loading_file', '正在加载文件')}: {file_path}...")
        
        # 使用文件加载器加载文件
        self.file_loader.load_file(file_path, table_name, options)
        
    def open_file_directly(self, file_path: str):
        """直接打开文件（用于命令行参数或文件关联）
        
        Args:
            file_path: 文件路径
        """
        if not os.path.exists(file_path):
            logger.error(f"文件不存在: {file_path}")
            self.sql_status_label.setText(f"{tr('error_file_not_found', '文件不存在')}: {file_path}")
            return
            
        # 检查文件扩展名
        suffix = Path(file_path).suffix.lower()
        if suffix not in ['.csv', '.parquet', '.pq']:
            logger.error(f"不支持的文件类型: {suffix}")
            self.sql_status_label.setText(f"{tr('error_unsupported_file_type', '不支持的文件类型')}: {suffix}")
            return
            
        # 自动生成表名
        table_name = Path(file_path).stem.replace(' ', '_').replace('-', '_')
        
        # 根据文件扩展名设置默认选项
        options = {}
        if suffix == '.csv':
            # CSV默认选项
            options["delimiter"] = settings.get("csv_delimiter", ",")
            options["encoding"] = settings.get("default_encoding", "UTF-8")
            options["has_header"] = settings.get("csv_has_header", True)
        
        logger.info(f"直接打开文件: {file_path}, 表名: {table_name}")
        
        # 加载文件
        self._load_file(file_path, table_name, options)
        
        # 添加到最近文件列表
        settings.add_recent_file(file_path)
        self._update_recent_files_menu()
        
    def _on_file_loaded(self, success: bool, message: str):
        """文件加载完成处理"""
        if success:
            self.sql_status_label.setText(message)
            # 刷新表结构视图
            self.schema_dock.refresh()
        else:
            self.sql_status_label.setText(f"{tr('error_loading_failed', '加载失败')}: {message}")
            
    def _update_recent_files_menu(self):
        """更新最近文件菜单"""
        self.recent_menu.clear()
        
        recent_files = settings.get_recent_files()
        
        if not recent_files:
            no_files_action = QAction(tr("menu_recent_no_files", "无最近文件"), self)
            no_files_action.setEnabled(False)
            self.recent_menu.addAction(no_files_action)
            return
            
        for file_path in recent_files:
            if os.path.exists(file_path):
                file_name = os.path.basename(file_path)
                action = QAction(file_name, self)
                action.setData(file_path)
                action.triggered.connect(self._open_recent_file)
                self.recent_menu.addAction(action)
                
        self.recent_menu.addSeparator()
        
        # 清空最近文件
        clear_action = QAction(tr("menu_recent_clear", "清空最近文件"), self)
        clear_action.triggered.connect(self._clear_recent_files)
        self.recent_menu.addAction(clear_action)
        
    def _open_recent_file(self):
        """打开最近文件"""
        action = self.sender()
        if action and isinstance(action, QAction):
            file_path = action.data()
            if file_path and os.path.exists(file_path):
                # 自动生成表名
                table_name = Path(file_path).stem.replace(' ', '_').replace('-', '_')
                
                # 根据文件扩展名判断选项
                options = {}
                suffix = Path(file_path).suffix.lower()
                
                if suffix == '.csv':
                    # CSV默认选项
                    options["delimiter"] = settings.get("csv_delimiter", ",")
                    options["encoding"] = settings.get("default_encoding", "UTF-8")
                
                # 加载文件
                self._load_file(file_path, table_name, options)
                
    def _clear_recent_files(self):
        """清空最近文件"""
        reply = QMessageBox.question(
            self, 
            tr("confirm_clear_recent", "确认清空"), 
            tr("confirm_clear_recent_message", "确定要清空最近文件列表吗？"), 
            QMessageBox.Yes | QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            settings.set("recent_files", [])
            settings.save_settings()
            self._update_recent_files_menu()
            
    def _execute_current_query(self):
        """执行当前查询"""
        tab = self.sql_editor.current_tab()
        if tab:
            tab.execute_query()
            
    def _stop_current_query(self):
        """停止当前查询"""
        tab = self.sql_editor.current_tab()
        if tab:
            tab.cancel_query()
            
    def _format_current_query(self):
        """格式化当前查询"""
        tab = self.sql_editor.current_tab()
        if tab:
            tab.format_sql()
            
    def _show_preferences(self):
        """显示偏好设置对话框"""
        dialog = PreferencesDialog(self)
        result = dialog.exec_()
        if result == QDialog.Accepted:
            # 应用字体设置到所有编辑器
            if hasattr(self, 'sql_editor') and self.sql_editor:
                self.sql_editor.apply_font_settings()
            
            # 显示提示信息
            self.sql_status_label.setText(tr("status_settings_applied", "设置已应用"))
    
    def _show_about(self):
        """显示关于对话框"""
        QMessageBox.about(
            self,
            f"{tr('about_title', '关于')} {APP_NAME}",
            f"""
            <h3>{APP_NAME} v{APP_VERSION}</h3>
            <p>{tr('about_description', '一个基于PySide6和DuckDB的高性能CSV/Parquet文件阅读器')}</p>
            <p>{tr('about_features', '支持SQL查询和数据分析功能')}</p>
            """
        )
        
    def _load_window_state(self):
        """加载窗口状态"""
        window_state = settings.get("window_state")
        if window_state:
            try:
                # 将Base64编码的字符串解码回二进制数据
                decoded_state = base64.b64decode(window_state)
                self.restoreState(QByteArray(decoded_state))
            except Exception as e:
                logger.warning(f"还原窗口状态失败: {str(e)}")
                
    def _save_window_state(self):
        """保存窗口状态"""
        window_state = self.saveState().data()
        settings.save_window_state(window_state)
        
    def resizeEvent(self, event):
        """窗口大小变化事件
        
        Args:
            event: 大小变化事件
        """
        super().resizeEvent(event)
        
        # 延迟执行调整，确保主窗口已经重绘完成
        from PySide6.QtCore import QTimer
        QTimer.singleShot(10, self._adjust_dock_sizes)
        
    def _adjust_dock_sizes(self):
        """调整停靠窗口大小"""
        # 检查停靠窗口是否初始化
        if not hasattr(self, 'schema_dock') or not hasattr(self, 'history_dock') or not hasattr(self, 'results_dock'):
            return
            
        # 计算合适的宽度比例
        left_width = self.width() * 0.2
        right_width = self.width() * 0.2
        bottom_height = self.height() * 0.35
        
        # 调整表结构宽度
        if self.schema_dock.isVisible():
            self.resizeDocks([self.schema_dock], [left_width], Qt.Horizontal)
            
        # 调整查询历史宽度
        if self.history_dock.isVisible():
            self.resizeDocks([self.history_dock], [right_width], Qt.Horizontal)
            
        # 调整结果窗口高度
        if self.results_dock.isVisible() and not self.results_dock.is_maximized:
            self.resizeDocks([self.results_dock], [bottom_height], Qt.Vertical)
        
    def closeEvent(self, event):
        """关闭窗口事件
        
        Args:
            event: 关闭事件
        """
        # 保存窗口状态
        self._save_window_state()
        
        # 接受关闭事件
        event.accept()

    def _on_query_executed(self, query_id, result):
        """处理查询执行完成
        
        Args:
            query_id: 查询ID
            result: 查询结果
        """
        # 将查询结果显示到结果窗口
        self.results_dock.display_result(result)

    def _on_tab_added(self, tab):
        """新标签页添加时的处理"""
        # 连接查询执行信号
        tab.query_executed.connect(self._on_query_executed)
        
        # 连接状态信号
        self._connect_tab_signals(tab)

    def _update_theme_menu(self):
        """更新主题菜单的选中状态"""
        current_setting = self.style_manager.get_theme_setting()
        
        for action in self.theme_action_group.actions():
            action_data = action.data()
            if current_setting == "auto" and action_data == "auto":
                action.setChecked(True)
            elif current_setting == action_data:
                action.setChecked(True)
                
    def _change_theme(self, theme_name: str):
        """切换主题
        
        Args:
            theme_name: 主题名称
        """
        if self.style_manager.set_theme(theme_name):
            logger.info(f"主题已切换为: {theme_name}")
        else:
            logger.error(f"切换主题失败: {theme_name}")
            # 恢复原来的选中状态
            self._update_theme_menu()
